package opd.servlets.helpers;

import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

import opd.db.helpers.Query;

public class ReportDates {
	private Date dateFrom;
	private Date dateTo;
	
	private Date avgDateFrom;
	private Date avgDateTo;
	
	private List<Date> report3DatesBack;
	
	// ----------------------------------------------------------------------------------------------------
	
	public ReportDates() {
		this.dateTo = getLastProductionDate();
		
		Calendar dateFromCalendar = Calendar.getInstance();
		dateFromCalendar.set(dateFromCalendar.get(Calendar.YEAR) , dateFromCalendar.get(Calendar.MONTH), 1);
		this.dateFrom = dateFromCalendar.getTime();
		
		
		Calendar avgDateFromCalendar = Calendar.getInstance();
		avgDateFromCalendar.setTime(getLastProductionDate());
		avgDateFromCalendar.add(Calendar.MONTH, -1);
		avgDateFromCalendar.set(Calendar.DATE, 1);
		
		this.avgDateFrom = avgDateFromCalendar.getTime();
		
		
		Calendar avgDateToCalendar = new GregorianCalendar(avgDateFromCalendar.get(Calendar.YEAR) , avgDateFromCalendar.get(Calendar.MONTH), avgDateFromCalendar.get(Calendar.DAY_OF_MONTH));
		avgDateToCalendar.set(Calendar.DAY_OF_MONTH, avgDateToCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		this.avgDateTo = avgDateToCalendar.getTime();
	}
	
	// ----------------------------------------------------------------------------------------------------
	
	public ReportDates(int daysBack){
		this.report3DatesBack = new ArrayList<Date>();
		this.report3DatesBack.add(getLastProductionDate());
		
		Calendar someDateCalendar = Calendar.getInstance();
		someDateCalendar.add(Calendar.DAY_OF_MONTH, -1);
		
		for (int i=1; i<daysBack; i++){			
			while (!isWorkingDay(someDateCalendar.getTime())){
				someDateCalendar.add(Calendar.DAY_OF_MONTH, -1);
			}
			this.report3DatesBack.add(someDateCalendar.getTime());
			
			someDateCalendar.add(Calendar.DAY_OF_MONTH, -1);
		}
	}
	
	// ----------------------------------------------------------------------------------------------------
	
	
    public Date getLastProductionDate() {
        Calendar today = Calendar.getInstance();
        Calendar lastProductionDate = today;
        
//        System.out.println(Calendar.getInstance().get(Calendar.HOUR_OF_DAY) < 18 && Calendar.getInstance().get(Calendar.MINUTE) < 30);
        
        if (Calendar.getInstance().get(Calendar.HOUR_OF_DAY) < 18 && Calendar.getInstance().get(Calendar.MINUTE) < 30) {
            lastProductionDate.add(Calendar.DAY_OF_MONTH, -1);
        }

        if (lastProductionDate.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
        	lastProductionDate.add(Calendar.DAY_OF_MONTH, -1);
        }

        if (lastProductionDate.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            lastProductionDate.add(Calendar.DAY_OF_MONTH, -2);
        }

        while (isHoliday(lastProductionDate.getTime())) {
        	lastProductionDate.add(Calendar.DAY_OF_MONTH, -1);
        }

        return lastProductionDate.getTime();
    }
    
    // ----------------------------------------------------------------------------------------------------
    
    private boolean isWorkingDay(Date date){
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(date);
    	
        if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return false;
        }

        return !isHoliday(date);
    }
    
    // ----------------------------------------------------------------------------------------------------
    
    private boolean isHoliday(Date dateTime) {
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(dateTime);
    	
        if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return false;
        }
        
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        
        if ((month == Calendar.JANUARY && day == 1) ||
            (month == Calendar.JANUARY && day == 6) ||
            (month == Calendar.FEBRUARY && day == 23) || // Καθαρή Δευτέρα
            (month == Calendar.MARCH && day == 25) ||
            (month == Calendar.APRIL && day == 10) || // Μεγάλη Παρασκευή
            (month == Calendar.APRIL && day == 13) || // Δευτέρα του Πάσχα
            (month == Calendar.MAY && day == 1) ||
            (month == Calendar.MAY && day == 31) || // Πεντηκοστή
            (month == Calendar.AUGUST && day == 15) ||
            (month == Calendar.OCTOBER && day == 28) ||
            (month == Calendar.DECEMBER && day == 25) ||
            (month == Calendar.DECEMBER && day == 26)
            ) {
            return true;
        }
        return false;
    }

    // ----------------------------------------------------------------------------------------------------
    
	public Date getDateFrom() {
		return dateFrom;
	}

	// ----------------------------------------------------------------------------------------------------
	
	public void setDateFrom(Date dateFrom) {
		this.dateFrom = dateFrom;
	}

	// ----------------------------------------------------------------------------------------------------
	
	public Date getDateTo() {
		return dateTo;
	}

	// ----------------------------------------------------------------------------------------------------
	
	public Date getAvgDateFrom() {
		return avgDateFrom;
	}

	// ----------------------------------------------------------------------------------------------------
	
	public void setAvgDateFrom(Date avgDateFrom) {
		this.avgDateFrom = avgDateFrom;
	}

	// ----------------------------------------------------------------------------------------------------
	
	public Date getAvgDateTo() {
		return avgDateTo;
	}

	// ----------------------------------------------------------------------------------------------------
	
	public void setAvgDateTo(Date avgDateTo) {
		this.avgDateTo = avgDateTo;
	}

	// ----------------------------------------------------------------------------------------------------
	
	public void setDateTo(Date dateTo) {
		this.dateTo = dateTo;
	}

	// ----------------------------------------------------------------------------------------------------
	
	public static String getMonthNameAndYear(Date date) {
		//Get Month Name of date
		Format dateFormat = new SimpleDateFormat("MMMM", Locale.forLanguageTag("EL"));
		String montnameAndYear = dateFormat.format(date);
		
		//get year of date
		Calendar avgDateFromCalendar = Calendar.getInstance();
		avgDateFromCalendar.setTime(date);
		
		return String.format("%s %s",  montnameAndYear, avgDateFromCalendar.get(Calendar.YEAR));
	}
	
	// ----------------------------------------------------------------------------------------------------
	
	public List<Date> getReport3DatesBack() {
		return report3DatesBack;
	}
	
	// ----------------------------------------------------------------------------------------------------
	
	
	public static void main(String[] args) {
//		ReportDates reportDates = new ReportDates();
//		
//		System.out.println(String.format("Date From: %s  Date To: %s", reportDates.getDateFrom(), reportDates.getDateTo()));
//		System.out.println(String.format("Avg Date From: %s  Avg Date To: %s", reportDates.getAvgDateFrom(), reportDates.getAvgDateTo()));
//		
//		Format dateFormat =  new SimpleDateFormat("MMMM", Locale.forLanguageTag("EL"));
//		
//		String montnameAndYear = dateFormat.format(reportDates.getAvgDateFrom());
//		
//		Calendar avgDateFromCalendar = Calendar.getInstance();
//		avgDateFromCalendar.setTime(reportDates.getAvgDateFrom());
//		
//		System.out.println(String.format("%s %s",  montnameAndYear, avgDateFromCalendar.get(Calendar.YEAR)));
		
//		String sToEscape = StringEscapeUtils.escapeJavaScript("Καλημέρα");
//		String jsValidEscapedS = sToEscape.replace('\\', '%') ;
//		
//		
//		System.out.println(sToEscape);
//		System.out.println(jsValidEscapedS);
		
		ReportDates reportDates = new ReportDates(5);
		
//		System.out.println(reportDates.getReport3DatesBack().size());
		//System.out.println(reportDates.getReport3DatesBack());
		
		Query query = new Query(Query.SELECT_QUERY);
		String[] inExpression = new String[reportDates.getReport3DatesBack().size()]; 
		//inExpression = reportDates.getReport3DatesBack().toArray(inExpression);
				
		for (int i=0; i<inExpression.length; i++){
			inExpression[i] = "?";
		}
		
		query.setWhere("WORKING_DATE", "IN", inExpression);
//		
		System.out.println(query.getWere());
		
		for (int i=0; i<reportDates.getReport3DatesBack().size(); i++){
			System.out.println(String.format("(%s) %s", i+1, reportDates.getReport3DatesBack().get(i)));
		}
	}
}
